﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.DependencyInjection;
using Simple.Common.EntityFrameworkCore.Repository;
using System;
using System.Linq;
using System.Reflection;

namespace Simple.Common.EntityFrameworkCore
{
    public static class EntityFrameworkCoreModule
    {
        public static void AddEntityFrameworkCoreServices<TDbContext>(this IServiceCollection services) where TDbContext : DbContext
        {
            var primaryKeyType = typeof(Guid);
            var dbContextType = typeof(TDbContext);

            //注入每个实体仓库 
            //var entities = from property in dbContextType.GetProperties(BindingFlags.Public | BindingFlags.Instance)
            //               where ReflectionHelper.IsAssignableToGenericType(property.PropertyType, typeof(DbSet<>))
            //               select new { EntityType = property.PropertyType.GenericTypeArguments[0], DeclaringType = property.DeclaringType };
            var entities = dbContextType.GetProperties()
                .Where(x => x.PropertyType.IsGenericType && x.PropertyType.DeclaringType != typeof(DbContext) && x.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
                .Select(x=>new { EntityType = x.PropertyType.GenericTypeArguments[0], DeclaringType = x.DeclaringType })
                .ToList();
            foreach (var entity in entities)
            {
                var prototype = typeof(IRepository<>).MakeGenericType(entity.EntityType);
                var efPrototype = typeof(Repository<,>).MakeGenericType(entity.DeclaringType, entity.EntityType);
                services.AddScoped(prototype, efPrototype);
                var prototypeRead = typeof(IRepository<>).MakeGenericType(entity.EntityType);
                var efPrototypeRead = typeof(Repository<,>).MakeGenericType(entity.DeclaringType, entity.EntityType);
                services.AddScoped(prototype, efPrototype);
            }
            services.AddDbContext<TDbContext>(ServiceLifetime.Scoped);
        }
    }
}
